package org.gameg.service.impl;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.gameg.bean.Game;
import org.gameg.bean.Player;
import org.gameg.bean.Power;
import org.gameg.mapper.TGameMapper;
import org.gameg.model.TGame;
import org.gameg.model.TGamePlayer;
import org.gameg.model.TGamePower;
import org.gameg.model.TPlayer;
import org.gameg.service.IGamePlayerService;
import org.gameg.service.IGamePowerService;
import org.gameg.service.IGameService;
import org.gameg.service.IPlayerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.alibaba.dubbo.config.annotation.Service;
import com.weibo.api.motan.config.springsupport.annotation.MotanService;

import top.ibase4j.core.base.BaseService;
import top.ibase4j.core.exception.BusinessException;
import top.ibase4j.core.util.InstanceUtil;

/**
 * @author ShenHuaJie
 * @since 2018年4月21日 下午7:26:41
 */
@CacheConfig(cacheNames = "TGame")
@Service(interfaceClass = IGameService.class)
@MotanService(interfaceClass = IGameService.class)
public class GameServiceImpl extends BaseService<TGame, TGameMapper> implements IGameService {
    final Logger logger = LogManager.getLogger();
    static final String NIUNIU = "1";
    static final String BAIJIALE = "2";
    static final String DXDSH = "3";
    static final String TEMA = "4";
    @Autowired
    private IPlayerService playerService;
    @Autowired
    private IGamePlayerService gamePlayerService;
    @Autowired
    private IGamePowerService gamePowerService;
    private static ExecutorService executorService = Executors.newFixedThreadPool(50);

    @Transactional
    public void updateGameConfig(Game game) {
        TGame tGame = InstanceUtil.to(game, TGame.class);
        tGame = update(tGame);
        for (Power power : game.getPowers()) {
            TGamePower gamePower = InstanceUtil.to(power, TGamePower.class);
            gamePower.setGameId(tGame.getId());
            gamePowerService.update(gamePower);
        }
        for (Player player : game.getPlayers()) {
            TGamePlayer record = new TGamePlayer();
            record.setGameId(tGame.getId());
            record.setPlayerId(player.getId());
            record.setCreateBy(player.getId());
            if ("Y".equals(game.getHdZJ())) {
                if ("Y".equals(player.getIsZj())) {
                    record.setIsZj("Y");
                } else {
                    throw new BusinessException("只有庄家才能提交游戏配置.");
                }
            }
            gamePlayerService.update(record);
            tGame.setCreateBy(player.getId());
            update(tGame);
        }
    }

    @Transactional
    public void addGamePlayer(Player player) {
        gamePlayerService.update(InstanceUtil.to(player, TGamePlayer.class));
        executorService.execute(new Runnable() {
            public void run() {

            }
        });
    }

    /**
     * @param game 配置
     * @return
     */
    @Transactional
    public List<TGamePlayer> updateGameResult(Game game) {
        List<TGamePlayer> resultList = InstanceUtil.newArrayList();
        String hz = game.getHdZJ(); // 是否有庄家
        Player zh = null;
        List<Player> xians = InstanceUtil.newArrayList();
        Map<Integer, Power> powers = InstanceUtil.newHashMap();
        for (Power power : game.getPowers()) {
            powers.put(power.getPoint(), power);
        }
        TGame tGame = InstanceUtil.to(game, TGame.class);
        tGame = update(tGame);
        for (Player player : game.getPlayers()) {
            player.setPoint(PointHelper.getPoint(game, powers, player.getAmount()));
            if ("Y".equals(hz) && "Y".equals(player.getIsZj())) {
                zh = player;
            } else if ("Y".equals(hz)) {
                xians.add(player);
            }
        }
        if ("Y".equals(hz) && zh == null) {
            throw new BusinessException("缺少庄家");
        }
        String gmp = game.getGmp(); // 游戏类型
        if ("Y".equals(hz)) { // 有庄模式
            int zhScore = 0;
            switch (gmp) {
            case NIUNIU:
                for (Player xian : xians) {
                    int result = PointHelper.compare(zh, xian);
                    TGamePlayer gamePlayer = InstanceUtil.to(xian, TGamePlayer.class);
                    if (result == 1) { // 庄赢
                        logger.warn("闲家{}输，庄家{}赢", xian.getWxId(), zh.getWxId());
                        int score = xian.getBet() * powers.get(zh.getPoint()).getPower();
                        zhScore += score;
                        if (!"Y".equals(game.getOnlyPoint())) {
                            updatePlayerScore(xian, -score);
                        }
                        gamePlayer.setCreditScore(-score);
                    } else if (result == -1) { // 闲赢
                        logger.warn("闲家{}赢，庄家{}输", xian.getWxId(), zh.getWxId());
                        int score = xian.getBet() * powers.get(xian.getPoint()).getPower();
                        zhScore -= score;
                        if (!"Y".equals(game.getOnlyPoint())) {
                            updatePlayerScore(xian, score);
                        }
                        gamePlayer.setCreditScore(score);
                    } else { // 打平
                        logger.warn("闲家{}和庄家{}打平", xian.getWxId(), zh.getWxId());
                        gamePlayer.setCreditScore(0);
                    }
                    gamePlayer.setGameId(tGame.getId());
                    gamePlayer = gamePlayerService.update(gamePlayer);
                    resultList.add(gamePlayer);
                }
                break;
            case BAIJIALE:

                break;
            case DXDSH:

                break;
            case TEMA:

                break;
            }
            if (!"Y".equals(game.getOnlyPoint())) {
                updatePlayerScore(zh, zhScore);
            }
            TGamePlayer gamePlayer = InstanceUtil.to(zh, TGamePlayer.class);
            gamePlayer.setGameId(tGame.getId());
            gamePlayer.setCreditScore(zhScore);
            gamePlayer = gamePlayerService.update(gamePlayer);
            resultList.add(gamePlayer);
        } else { // 无庄模式
            Assert.isTrue(game.getPlayers().size() == 2, "游戏配置错误");
            switch (gmp) {
            case NIUNIU:
                Player player1 = game.getPlayers().get(0);
                Player player2 = game.getPlayers().get(1);

                int result = PointHelper.compare(player1, player2);
                TGamePlayer gamePlayer1 = InstanceUtil.to(player1, TGamePlayer.class);
                TGamePlayer gamePlayer2 = InstanceUtil.to(player2, TGamePlayer.class);
                if (result == 1) { // 玩家1赢
                    logger.warn("玩家{}赢，玩家{}赢输", player1.getWxId(), player2.getWxId());
                    int score = player2.getBet() * powers.get(player1.getPoint()).getPower();
                    if (!"Y".equals(game.getOnlyPoint())) {
                        updatePlayerScore(player1, score);
                        updatePlayerScore(player2, -score);
                    }
                    gamePlayer1.setCreditScore(score);
                    gamePlayer2.setCreditScore(-score);
                } else if (result == -1) { // 玩家2赢
                    logger.warn("玩家{}赢，玩家{}赢输", player2.getWxId(), player1.getWxId());
                    int score = player1.getBet() * powers.get(player2.getPoint()).getPower();
                    if (!"Y".equals(game.getOnlyPoint())) {
                        updatePlayerScore(player1, -score);
                        updatePlayerScore(player2, score);
                    }
                    gamePlayer1.setCreditScore(-score);
                    gamePlayer2.setCreditScore(score);
                } else { // 打平
                    logger.warn("玩家{}和玩家{}打平", player1.getWxId(), player2.getWxId());
                    gamePlayer1.setCreditScore(0);
                    gamePlayer2.setCreditScore(0);
                }
                gamePlayer1.setGameId(tGame.getId());
                gamePlayer1 = gamePlayerService.update(gamePlayer1);
                resultList.add(gamePlayer1);
                gamePlayer2.setGameId(tGame.getId());
                gamePlayer2 = gamePlayerService.update(gamePlayer2);
                resultList.add(gamePlayer2);
                break;
            case BAIJIALE:

                break;
            case DXDSH:

                break;
            case TEMA:

                break;
            }
        }
        return resultList;
    }

    private void updatePlayerScore(Player player, Integer score) {
        TPlayer param = InstanceUtil.to(player, TPlayer.class);
        TPlayer record = playerService.selectOne(param);
        if (record != null) {
            record.setCreditScore(record.getCreditScore() + score);
            playerService.update(record);
        }
    }
}
